package com.um.weixin.pay.service;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.exception.WxPayException;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author 邓南辉
 * 日期 2023/5/11
 * 版权所有 广州优匠科技有限公司
 */
public interface WxBasePayService {

    /**
     * JSAPI下单
     * @param outTradeNo
     * @param openId
     * @param amount
     * @param description
     * @param notifyUrl
     * @return
     * @throws WxPayException
     */
    WxPayUnifiedOrderV3Result.JsapiResult createOrderByJsapi(String outTradeNo, String openId, Integer amount,
                                                             String description, String notifyUrl) throws WxPayException;

    /**
     * JSAPI下单
     * @param outTradeNo
     * @param openId
     * @param amount
     * @param description
     * @param notifyUrl
     * @return
     * @throws WxPayException
     */
    WxPayUnifiedOrderV3Result.JsapiResult createOrderByJsapi(String outTradeNo, String openId, Integer amount,
                                                             String description, String notifyUrl, boolean isProfitSharing) throws WxPayException;

    /**
     * JSAPI下单
     * @param outTradeNo
     * @param openId
     * @param amount
     * @param description
     * @param notifyUrl
     * @return
     * @throws WxPayException
     */
    WxPayUnifiedOrderV3Result.JsapiResult createOrderByJsapi(String outTradeNo, String openId, Integer amount,
                                                             String description, String notifyUrl, boolean isProfitSharing,
                                                             Date timeExpire) throws WxPayException;

    /**
     * 调用统一下单接口，并组装生成支付所需参数对象.
     *
     * @param <T>       请使用{@link com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result}里的内部类或字段
     * @param tradeType the trade type
     * @param request   统一下单请求参数
     * @return 返回 {@link com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result}里的内部类或字段
     * @throws WxPayException the wx pay exception
     */
    <T> T createOrder(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request) throws WxPayException;

    /**
     * 申请退款
     * @param outTradeNo
     * @param outRefundNo
     * @param payAmount
     * @param refundAmount
     * @return
     */
    WxPayRefundV3Result refundOrder(String outTradeNo, String outRefundNo, Integer payAmount, Integer refundAmount) throws WxPayException;

    /**
     * 申请退款
     * @param outTradeNo
     * @param outRefundNo
     * @param payAmount
     * @param refundAmount
     * @param notifyUrl
     * @return
     */
    WxPayRefundV3Result refundOrder(String outTradeNo, String outRefundNo, Integer payAmount, Integer refundAmount, String notifyUrl) throws WxPayException;

    /**
     * 申请退款
     * @param outTradeNo
     * @param outRefundNo
     * @param payAmount
     * @param refundAmount
     * @param notifyUrl
     * @return
     */
    WxPayRefundV3Result refundOrder(String outTradeNo, String transactionId, String outRefundNo, Integer payAmount, Integer refundAmount, String notifyUrl) throws WxPayException;

    /**
     * <pre>
     * 申请退款API（支持单品）.
     * 详见 <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml</a>
     *
     * 应用场景
     * 当交易发生之后一年内，由于买家或者卖家的原因需要退款时，卖家可以通过退款接口将支付金额退还给买家，微信支付将在收到退款请求并且验证成功之后，将支付款按原路退还至买家账号上。
     *
     * 注意：
     * 1、交易时间超过一年的订单无法提交退款
     * 2、微信支付退款支持单笔交易分多次退款（不超50次），多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交，请不要更换退款单号，请使用原商户退款单号
     * 3、错误或无效请求频率限制：6qps，即每秒钟异常或错误的退款申请请求不超过6次
     * 4、每个支付订单的部分退款次数不能超过50次
     * 5、如果同一个用户有多笔退款，建议分不同批次进行退款，避免并发退款导致退款失败
     * 6、申请退款接口的返回仅代表业务的受理情况，具体退款是否成功，需要通过退款查询接口获取结果
     * 7、一个月之前的订单申请退款频率限制为：5000/min
     *
     * 接口地址
     * https://api.mch.weixin.qq.com/v3/refund/domestic/refunds
     * </pre>
     *
     * @param request 请求对象
     * @return 退款操作结果 wx pay refund result
     * @throws WxPayException the wx pay exception
     */
    WxPayRefundV3Result refundOrder(WxPayRefundV3Request request) throws WxPayException;

    /**
     * 解析支付结果v3通知.
     * 详见https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
     *
     * @return the wx pay order notify result
     * @throws WxPayException the wx pay exception
     */
    WxPayNotifyV3Result parseOrderNotify(HttpServletRequest request) throws WxPayException;

    /**
     * 解析退款结果通知
     * 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=9
     * @return the wx pay refund notify result
     * @throws WxPayException the wx pay exception
     */
    WxPayRefundNotifyV3Result parseRefundNotifyV3Result(HttpServletRequest request) throws WxPayException;

}
